#!/usr/bin/python
# -*- coding: utf-8 -*-

import unittest

# here is the generic adapter proposed in the GITS blog :
# see details here http://ginstrom.com/scribbles/2008/11/06/generic-adapter-class-in-python/
class GenericAdapter(object):
    """
    Adapts an object by replacing methods.
    Usage:
    dog = Dog()
    dog = GenericAdapter(dog, dict(make_noise=dog.bark))
    """
    def __init__(self, obj, adapted_methods):
        """We set the adapted methods in the object's dict"""
        self.obj = obj
        self.__dict__.update(adapted_methods)
    def __getattr__(self, attr):
        """All non-adapted calls are passed to the object"""
        return getattr(self.obj, attr)

# lets do the sample in classical adapter again
# you can see that there is far less code !

# A cat class
class MyCat(object):
    def meow(self):
        return "My cat meows."

# A car class 
class MyCar(object):    
    def vroom(self):
        return "My car vrooms."

class TestGenericAdapter(unittest.TestCase):
    
    def setUp(self):
        unittest.TestCase.setUp(self)
    
    def tearDown(self):
        unittest.TestCase.tearDown(self)
        
    def testAdapter(self):
        """Generic adapter creation"""
        # create a cat adapter
        a_cat = MyCat()
        my_cat_adapted = GenericAdapter(a_cat, dict(make_noise=a_cat.meow))
        # create car adapter
        a_car = MyCar()
        my_car_adapted = GenericAdapter(a_car, dict(make_noise=a_car.vroom))
        
        self.assertEqual(my_cat_adapted.make_noise(), "My cat meows.")
        self.assertEqual(my_car_adapted.make_noise(), "My car vrooms.")
        
    def test_class_inheritance(self):
        """Generic adapter and inheritance"""
        # create a cat adapter
        a_cat = MyCat()
        my_cat_adapted = GenericAdapter(a_cat, dict(make_noise=a_cat.meow))
        
        # my_car_adapted is a instance of GenericAdapter...
        self.assertTrue(isinstance(my_cat_adapted, GenericAdapter))
        # but not of
        self.assertFalse(isinstance(my_cat_adapted, MyCar))
        
    def test_class_inheritance2(self):
        """Generic adapter and inheritance"""
        # if you need a more specific class than GenericAdapter, you can use:
        class MyClassAdapter(GenericAdapter):
            pass
        
        a_cat = MyCat()
        my_cat_adapted = MyClassAdapter(a_cat, dict(make_noise=a_cat.meow))
        # my_car_adapted is a instance of GenericAdapter...
        self.assertTrue(isinstance(my_cat_adapted, GenericAdapter))
        # but not of ...
        self.assertFalse(isinstance(my_cat_adapted, MyCar))
        # but of MyClassAdapter !
        self.assertTrue(isinstance(my_cat_adapted, MyClassAdapter))
        
        
if __name__ == '__main__':
    unittest.main()
    

